package com.system.service.impl;

import com.common.core.cookie.GenerateCookie;
import com.common.enums.BaseResponseCode;
import com.common.utils.AjaxResult;
import com.common.utils.MD5Utils;
import com.system.entity.SysUserEntity;
import com.system.mapper.SysUserMapper;
import com.system.service.ISysUserRoleService;
import com.system.service.SysUserService;
import com.vo.LoginVo;
import com.vo.UserVO;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

@Service
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ISysUserRoleService sysUserUserRoleService;

    /**
     * 数据添加
     *
     * @param sysUserEntity
     */

    @Override
    public AjaxResult sysUserAdd(SysUserEntity sysUserEntity) {
        int n = sysUserMapper.sysUserAdd(sysUserEntity);
        return new AjaxResult(BaseResponseCode.ADD_SUCCESS.getCode(), BaseResponseCode.ADD_SUCCESS.getMsg());
    }

    /**
     * 删除与批量删除
     *
     * @param ids
     */
    @Override
    @Transactional
    public AjaxResult sysUserDel(List<Integer> ids) {
        sysUserMapper.sysUserDel(ids);
        return new AjaxResult(BaseResponseCode.DELETE_SUCCESS.getCode(), BaseResponseCode.DELETE_SUCCESS.getMsg());
    }

    /**
     * 更新
     *
     * @param sysUserEntity
     */
    @Override
    public AjaxResult sysUserUpById(SysUserEntity sysUserEntity) {
        sysUserMapper.sysUserUpById(sysUserEntity);
        return new AjaxResult(BaseResponseCode.UPDATE_SUCCESS.getCode(), BaseResponseCode.UPDATE_SUCCESS.getMsg());
    }

    /**
     * 查询单个数据
     */
    @Override
    public SysUserEntity sysUserGetById(String id) {
        return sysUserMapper.sysUserGetById(id);
    }

    /**
     * 查询数据库
     *
     * @return
     */
    @Override
    public AjaxResult sysUserSelectListByPage(SysUserEntity sysUserEntity) {
        Integer count = sysUserMapper.sysUserSelCount();
        List<SysUserEntity> list = sysUserMapper.sysUserSelectListByPage(sysUserEntity);
        return AjaxResult.data(count, list);
    }

    /**
     * 登录校验
     *
     * @param loginVo
     * @param request
     * @param response
     * @return
     */

    @Override
    public AjaxResult toLogin(LoginVo loginVo, HttpServletRequest request, HttpServletResponse response) {

        Subject subject = SecurityUtils.getSubject();
        /*
            查询用户表是否有该用户
         */
        UserVO userVO = sysUserMapper.sysUserVOGetById(loginVo.getUserName());
        if (userVO == null) {
            return AjaxResult.error("用户不存在");
        }
        /*
        通过用户的id查询用户角色表
        是否已分配号角色给该用户
         */
        Long roleId = sysUserUserRoleService.sysUserRoleGetUserById(userVO.getUserId());
        if (roleId == null) {
            return AjaxResult.error("该用户未被分配角色,暂时无法登录");
        }
        UsernamePasswordToken token = new UsernamePasswordToken(
                loginVo.getUserName(), MD5Utils.houInputPassToFromPass(loginVo.getPassWord(), userVO.getSalt()));
        try {
            subject.login(token);
        } catch (UnknownAccountException | IncorrectCredentialsException e) {
            return AjaxResult.LoginERROR();
        }
        /*
            获取缓存中的token值
            如果有表示该用户已经在线
         */
        Object obj = redisTemplate.opsForValue().get("user:" + loginVo.getUserName());
        if (obj != null) {
            return AjaxResult.LoginERRORto();
        }
        GenerateCookie.generateCookie(request, response, redisTemplate, userVO);
        return AjaxResult.LoginSUCCESS();

    }

    /**
     * 强行登录
     * 因为在登录功能已经进行校验过了
     * 这就不需要校验
     *
     * @param loginVo
     * @param request
     * @param response
     * @return
     */
    @Override
    public AjaxResult toLoginTo(LoginVo loginVo, HttpServletRequest request, HttpServletResponse response) {
        String token = (String) redisTemplate.opsForValue().get("user:" + loginVo.getUserName());
        redisTemplate.delete("Token:" + token);
        UserVO userVO = sysUserMapper.sysUserVOGetById(loginVo.getUserName());
        GenerateCookie.generateCookie(request, response, redisTemplate, userVO);
        return AjaxResult.LoginSUCCESS();
    }

    /**
     * 退出登录
     *
     * @param userVO
     * @return
     */

    @Override
    public AjaxResult logout(UserVO userVO) {
        String token = (String) redisTemplate.opsForValue().get("user:" + userVO.getLoginName());
        redisTemplate.delete("user:" + userVO.getLoginName());
        redisTemplate.delete("Token:" + token);
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return new AjaxResult(200);
    }
}